package demo;

import lombok.extern.slf4j.Slf4j;

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.WeakHashMap;

/**
 * 强引用
 * 软引用
 * 弱引用
 * 虚引用
 * @author Javen
 */
@Slf4j
public class ReferenceDemo {

    /**
     * 软引用 内存不够的时候才会回收
     * -Xms5m -Xmx5m
     */
    public static void softReference() {
        Object obj = new Object();
        SoftReference<Object> softReference = new SoftReference<>(obj);
        log.info("Object: {}", obj);
        log.info("softReference Object: {}", softReference.get());

        obj = null;
        System.gc();

        log.info("gc ....");
        log.info("Object: {}", obj);
        log.info("softReference Object: {}", softReference.get());

    }

    /**
     * 弱引用 只要 gc 了就会回收，如果添加了 ReferenceQueue 队列回收后就会放到此队列中
     */
    public static void weakReference() {
        Object obj = new Object();
        ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
        WeakReference<Object> softReference = new WeakReference<>(obj, referenceQueue);
        log.info("Object: {}", obj);
        log.info("softReference Object: {}", softReference.get());
        log.info("referenceQueue : {}", referenceQueue.poll());

        obj = null;
        System.gc();

        log.info("gc ....");
        log.info("Object: {}", obj);
        log.info("softReference Object: {}", softReference.get());
        log.info("referenceQueue : {}", referenceQueue.poll());
    }

    /**
     * 虚引用
     * <p>
     * 如果一个对象仅持有虚引用，那么它就和没有任何引用一样，在任何时候都可能被垃圾器收回。
     * 回收后就会放到 ReferenceQueue 队列中
     */
    public static void phantomReference() {
        Object obj = new Object();
        ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
        PhantomReference<Object> phantomReference = new PhantomReference<>(obj, referenceQueue);
        log.info("Object: {}", obj);
        // 虚引用 get 永远返回 null 
        log.info("phantomReference Object: {}", phantomReference.get());
        log.info("referenceQueue : {}", referenceQueue.poll());

        obj = null;
        System.gc();

        log.info("gc ....");
        log.info("Object: {}", obj);
        log.info("phantomReference Object: {}", phantomReference.get());
        log.info("referenceQueue : {}", referenceQueue.poll());
    }


    /**
     * 弱引用 只要 gc 了就会回收
     */
    public static void weakHashMapReference() {
        Object key = new Integer(1);
        WeakHashMap<Object, Object> map = new WeakHashMap<>();
        map.put(key, "weakHashMapReference");
        log.info("map: {}", map);
        log.info("map Object: {}", map.get(key));

        key = null;
        System.gc();

        log.info("gc ....");
        log.info("map: {}", map);
        log.info("map Object: {}", map.size());
    }




    public static void main(String[] args) {
//        softReference();
//        weakReference();
        phantomReference();
//        weakHashMapReference();
    }
}
